﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using SH;


namespace MTS
{
    [StructLayout(LayoutKind.Sequential)]
    public struct mtCRegisterInfo
    {

        public int version; // sizeof(mtCRegisterInfo)
        public int stationType;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string stationName;   //站点名称
        public int programType;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string programName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string location;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string userName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string password;

        public byte bAutoConnect;
        public byte bAutoLogon;

        public uint nMaxHeartFailCount;
        public uint nConnectInterval;
        public uint nHeartInterval;

        // add by tangyetao 2020/07/15 注册信息中添加当前站点的语言环境ID
        public int nLanguageID;

        //sh_byte_t		cReserved[256];		//保留
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct mtCInvokeParam
    {
        public int version;
        public int ptType;
        public int nClassID;
        public int nFuncID;
        public byte bEpic;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string token;

    }

    [StructLayout(LayoutKind.Sequential)]
    public struct mtCDataParam
    {

        public int type;
        public long nLength;
        public IntPtr pParam;

    }

    [StructLayout(LayoutKind.Sequential)]
    public struct mtCCallabckParam
    {

        public int version;
        public int nClassID;
        public int nFuncID;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string token;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct mtCStationInfo
    {
        ulong m_handle;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string name;        //站点名称
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string guid;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string location;   //位置
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)]
        public string macAddress;   //位置
        public int stype;
        public int ptype;
        public byte bConnect;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string token;
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct mtCLogParam
    {
        public uint level;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string file;   //位置
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string func;    //位置
        public uint line;   //位置
        public IntPtr szStr;
    }
;

[StructLayout(LayoutKind.Sequential)]
    public struct mtCTest
    {
        public int version;
        public IntPtr pParam;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string token;

    }
;

class mtCHelptr
    {
        public static mtCInvokeParam MakeInvokeParam(int nC, int nF,emProgramType pt)
        {
            mtCInvokeParam IvkParam = new mtCInvokeParam
            {
                version = 0,
                ptType = (int)pt,
                nClassID = nC,
                nFuncID = nF,
                bEpic = (byte)(0),
            };

            return IvkParam;
        }

        public static mtCInvokeParam MakeInvokeParam( int nC, int nF)
        {
            mtCInvokeParam IvkParam = new mtCInvokeParam
            {
                version = 0,
                ptType = (int)emProgramType.emPT_Unknown,
                nClassID = nC,
                nFuncID = nF,
                bEpic = (byte)(1 ),
            };

            return IvkParam;
        }

        public   static mtCInvokeParam MakeInvokeParam(int nC,int nF,string token)
        {
            mtCInvokeParam IvkParam = new mtCInvokeParam
            {
                version = 0,
                ptType = (int)emProgramType.emPT_ALL,
                nClassID = nC,
                nFuncID = nF,
                bEpic = (byte)(0),
                token = token
            };

            return IvkParam;
        }

        public static mtCDataParam MakeDataParam(byte[] buf) 
        {
            mtCDataParam dataParam = new mtCDataParam
            {
                type = 0,
                nLength = buf.Length,
                pParam = Marshal.UnsafeAddrOfPinnedArrayElement(buf, 0)

            };

            return dataParam;
        }
        public static mtCDataParam MakeDataParam(MTSSerializer sc)
        {
            var buf = sc.ToArray();
            mtCDataParam dataParam = new mtCDataParam
            {
                type = 0,
                nLength = buf.Length,
                pParam = Marshal.UnsafeAddrOfPinnedArrayElement(buf, 0)

            };

            return dataParam;
        }

        public static mtCDataParam MakeDataOutParam(MTSSerializer sc)
        {
            var buf = sc.ToArray();
            mtCDataParam dataParam = new mtCDataParam
            {
                type = 0,
                nLength = buf.Length,
            };

            if (buf.Length > 0)
            {
                dataParam.pParam = MTSDLLWrap.getInstance().mtAllocMemory(buf.Length);

                Marshal.Copy(buf,0,dataParam.pParam, (int)dataParam.nLength);
            }       

            return dataParam;
        }

        public static mtCDataParam MakeEmptyDataParam()
        {
            mtCDataParam dataParam = new mtCDataParam
            {
                type = 0,
                nLength = 0,
            };

            return dataParam;
        }

        public static byte[] DataParamToBytes(mtCDataParam param)
        {
            if (param.nLength == 0)
                return new byte[0];
            else
            {
                try
                {
                    var buf = new byte[param.nLength];

                    Marshal.Copy(param.pParam, buf, 0, (int)param.nLength);

                    return buf;
                }
                catch (ArgumentNullException )
                {
                    return new byte[0];
                }
               
            }

        }

        public static byte[] DataParamOutToBytes(mtCDataParam param)
        {
            if (param.nLength == 0)
                return new byte[0];
            else
            {
                try
                {
                    if (param.nLength > 0)
                    {
                        var buf = new byte[param.nLength];

                        Marshal.Copy(param.pParam, buf, 0, (int)param.nLength);

                        MTSDLLWrap.getInstance().mtFreeMemory(param.pParam);

                        return buf;
                    }
                    else
                        return new byte[0];

                }
                catch (ArgumentNullException)
                {
                    return new byte[0];
                }

            }

        }

    }


    internal delegate shErrorCode degtOnCallbackOneWay(ulong handle, ref mtCCallabckParam pParam, ref mtCDataParam pData);

    internal delegate shErrorCode degtOnCallbackTwoWay(ulong handle, ref mtCCallabckParam pParam, ref mtCDataParam dataIn, ref mtCDataParam dataOut);

    internal delegate shErrorCode degtOnStationInfoNotify(ulong handle, ref mtCStationInfo info, int nFlag);

    internal delegate shErrorCode degtOnDelegate(ulong handle, ref mtCStationInfo info) ;


    internal interface IMTSDLLWrap
    {
        public  ulong mtInitialize();

        public  ulong mtUnInitialize();

        public ulong mtTraceOut(ref mtCLogParam param);

        public ulong mtCGet(ref mtCRegisterInfo info);

        public  void mtCRelease(ulong handle);

        public  void mtFreeMemory(IntPtr pVoid);

        public IntPtr mtAllocMemory(long nSize);

        public int mtInvokeOneWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam data);

        public int mtInvokeTwoWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam dataIn, ref mtCDataParam dataOut);

        public int mtSetCallback(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify);

        //以下测试接口用
        public int mtTestDelegate(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify);
    }


    internal sealed class MTSDLLWindows : IMTSDLLWrap
    {

        [DllImport(@"MessTransceiver_vc142x64.dll", EntryPoint = "mtInitialize", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe ulong _mtInitialize();

        [DllImport(@"MessTransceiver_vc142x64.dll", EntryPoint = "mtUnInitialize", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe ulong _mtUnInitialize();

        [DllImport(@"MessTransceiver_vc142x64.dll", EntryPoint = "mtTraceOut", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe ulong _mtTraceOut(ref mtCLogParam param);

        [DllImport(@"MessTransceiver_vc142x64.dll", EntryPoint = "mtCGet", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe ulong _mtCGet(ref mtCRegisterInfo info);

        [DllImport(@"MessTransceiver_vc142x64.dll", EntryPoint = "mtCRelease", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe void _mtCRelease(ulong handle);

        [DllImport(@"MessTransceiver_vc142x64.dll", EntryPoint = "mtFreeMemory", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe void _mtFreeMemory(IntPtr pVoid);

        [DllImport(@"MessTransceiver_vc142x64.dll", EntryPoint = "mtAllocMemory", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe IntPtr _mtAllocMemory(long nSize);

        [DllImport(@"MessTransceiver_vc142x64.dll", EntryPoint = "mtInvokeOneWay", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe int _mtInvokeOneWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam data);

        [DllImport(@"MessTransceiver_vc142x64.dll", EntryPoint = "mtInvokeTwoWay", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe int _mtInvokeTwoWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam dataIn, ref mtCDataParam dataOut);

        [DllImport(@"MessTransceiver_vc142x64.dll", EntryPoint = "mtSetCallback", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe int _mtSetCallback(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify);

        //以下测试接口用
        [DllImport(@"MessTransceiver_vc142x64.dll", EntryPoint = "mtTestDelegate", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe int _mtTestDelegate(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify);

        public ulong mtInitialize()
        {
           return _mtInitialize();
        }

        public ulong mtUnInitialize()
        {
            return _mtUnInitialize();
        }

        public ulong mtTraceOut(ref mtCLogParam param)
        {
            return _mtTraceOut(ref param);
        }

        public ulong mtCGet(ref mtCRegisterInfo info)
        {
            return _mtCGet(ref info);
        }

        public void mtCRelease(ulong handle)
        {
            _mtCRelease(handle);
        }

        public void mtFreeMemory(IntPtr pVoid)
        {
            _mtFreeMemory(pVoid);
        }

        public IntPtr mtAllocMemory(long nSize)
        {
            return _mtAllocMemory(nSize);
        }

        public int mtInvokeOneWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam data)
        {
             return _mtInvokeOneWay(handle,ref pInvoke,ref data);
        }

        public int mtInvokeTwoWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam dataIn, ref mtCDataParam dataOut)
        {
            return _mtInvokeTwoWay(handle,ref pInvoke,ref dataIn,ref dataOut);
        }

        public int mtSetCallback(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify)
        {
            return _mtSetCallback(handle,pfnCallbackOneWay,pfnCallbackTwoWay,pfnStationInfoNotify); 
        }

        public int mtTestDelegate(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify)
        {
            return _mtSetCallback(handle, pfnCallbackOneWay,pfnCallbackTwoWay,pfnStationInfoNotify);
        }
    }


    internal sealed class MTSDLLWrapLinux : IMTSDLLWrap
    {
        [DllImport(@"libMessTransceiver_x64.so", EntryPoint = "mtInitialize", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
         static extern unsafe ulong _mtInitialize();

        [DllImport(@"libMessTransceiver_x64.so", EntryPoint = "mtUnInitialize", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe ulong _mtUnInitialize();

        [DllImport(@"libMessTransceiver_x64.so", EntryPoint = "mtTraceOut", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe ulong _mtTraceOut(ref mtCLogParam param);

        [DllImport(@"libMessTransceiver_x64.so", EntryPoint = "mtCGet", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe ulong _mtCGet(ref mtCRegisterInfo info);

        [DllImport(@"libMessTransceiver_x64.so", EntryPoint = "mtCRelease", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe void _mtCRelease(ulong handle);

        [DllImport(@"libMessTransceiver_x64.so", EntryPoint = "mtFreeMemory", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe void _mtFreeMemory(IntPtr pVoid);

        [DllImport(@"libMessTransceiver_x64.so", EntryPoint = "mtAllocMemory", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe IntPtr _mtAllocMemory(long nSize);

        [DllImport(@"libMessTransceiver_x64.so", EntryPoint = "mtInvokeOneWay", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe int _mtInvokeOneWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam data);

        [DllImport(@"libMessTransceiver_x64.so", EntryPoint = "mtInvokeTwoWay", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe int _mtInvokeTwoWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam dataIn, ref mtCDataParam dataOut);
         
        [DllImport(@"libMessTransceiver_x64.so", EntryPoint = "mtSetCallback", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe int _mtSetCallback(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify);

        //以下测试接口用
        [DllImport(@"libMessTransceiver_x64.so", EntryPoint = "mtTestDelegate", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe int _mtTestDelegate(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify);

        public ulong mtInitialize()
        {
            return _mtInitialize();
        }
        public ulong mtUnInitialize()
        {
            return _mtUnInitialize();
        }

        public ulong mtTraceOut(ref mtCLogParam param)
        {
            return _mtTraceOut(ref param);
        }

        public ulong mtCGet(ref mtCRegisterInfo info)
        {
            return _mtCGet(ref info);
        }

        public void mtCRelease(ulong handle)
        {
            _mtCRelease(handle);
        }

        public void mtFreeMemory(IntPtr pVoid)
        {
            _mtFreeMemory(pVoid);
        }

        public IntPtr mtAllocMemory(long nSize)
        {
            return _mtAllocMemory(nSize);
        }

        public int mtInvokeOneWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam data)
        {
            return _mtInvokeOneWay(handle, ref pInvoke, ref data);
        }

        public int mtInvokeTwoWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam dataIn, ref mtCDataParam dataOut)
        {
            return _mtInvokeTwoWay(handle, ref pInvoke, ref dataIn, ref dataOut);
        }

        public int mtSetCallback(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify)
        {
            return _mtSetCallback(handle, pfnCallbackOneWay, pfnCallbackTwoWay, pfnStationInfoNotify);
        }

        public int mtTestDelegate(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify)
        {
            return _mtSetCallback(handle, pfnCallbackOneWay, pfnCallbackTwoWay, pfnStationInfoNotify);
        }
    }

    internal sealed class MTSDLLWrapOSX : IMTSDLLWrap
    {

        [DllImport(@"libMessTransceiver_x64.dylib", EntryPoint = "mtInitialize", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe ulong _mtInitialize();

        [DllImport(@"libMessTransceiver_x64.dylib", EntryPoint = "mtUnInitialize", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe ulong _mtUnInitialize();

        [DllImport(@"libMessTransceiver_x64.dylib", EntryPoint = "mtTraceOut", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe ulong _mtTraceOut(ref mtCLogParam param);

        [DllImport(@"libMessTransceiver_x64.dylib", EntryPoint = "mtCGet", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe ulong _mtCGet(ref mtCRegisterInfo info);

        [DllImport(@"libMessTransceiver_x64.dylib", EntryPoint = "mtCRelease", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe void _mtCRelease(ulong handle);

        [DllImport(@"libMessTransceiver_x64.dylib", EntryPoint = "mtFreeMemory", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe void _mtFreeMemory(IntPtr pVoid);

        [DllImport(@"libMessTransceiver_x64.dylib", EntryPoint = "mtAllocMemory", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe IntPtr _mtAllocMemory(long nSize);

        [DllImport(@"libMessTransceiver_x64.dylib", EntryPoint = "mtInvokeOneWay", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe int _mtInvokeOneWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam data);

        [DllImport(@"libMessTransceiver_x64.dylib", EntryPoint = "mtInvokeTwoWay", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe int _mtInvokeTwoWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam dataIn, ref mtCDataParam dataOut);

        [DllImport(@"libMessTransceiver_x64.dylib", EntryPoint = "mtSetCallback", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe int _mtSetCallback(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify);

        //以下测试接口用
        [DllImport(@"libMessTransceiver_x64.dylib", EntryPoint = "mtTestDelegate", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        static extern unsafe int _mtTestDelegate(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify);

        public ulong mtInitialize()
        {
            return _mtInitialize();
        }

        public ulong mtUnInitialize()
        {
            return _mtUnInitialize();
        }

        public ulong mtTraceOut(ref mtCLogParam param)
        {
            return _mtTraceOut(ref param);
        }

        public ulong mtCGet(ref mtCRegisterInfo info)
        {
            return _mtCGet(ref info);
        }

        public void mtCRelease(ulong handle)
        {
            _mtCRelease(handle);
        }

        public void mtFreeMemory(IntPtr pVoid)
        {
            _mtFreeMemory(pVoid);
        }

        public IntPtr mtAllocMemory(long nSize)
        {
            return _mtAllocMemory(nSize);
        }

        public int mtInvokeOneWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam data)
        {
            return _mtInvokeOneWay(handle, ref pInvoke, ref data);
        }

        public int mtInvokeTwoWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam dataIn, ref mtCDataParam dataOut)
        {
            return _mtInvokeTwoWay(handle, ref pInvoke, ref dataIn, ref dataOut);
        }

        public int mtSetCallback(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify)
        {
            return _mtSetCallback(handle, pfnCallbackOneWay, pfnCallbackTwoWay, pfnStationInfoNotify);
        }

        public int mtTestDelegate(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify)
        {
            return _mtSetCallback(handle, pfnCallbackOneWay, pfnCallbackTwoWay, pfnStationInfoNotify);
        }
    }

    class MTSDLLWrap : IMTSDLLWrap
    {
        IMTSDLLWrap wrap;
        public static object Flag = new object();
        private static MTSDLLWrap instance;
        private MTSDLLWrap()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                wrap = new MTSDLLWrapLinux();
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                wrap = new MTSDLLWrapOSX();
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                wrap = new MTSDLLWindows();
            else
                throw new NotSupportedException();
        }

        public static MTSDLLWrap getInstance()
        {
            if (instance == null)
            {
                lock (Flag)
                {
                    int i = 50000000;
                    while (i > 0)
                    { i--; }

                    instance = new MTSDLLWrap();
                }
            }

            return instance;
        }


        public ulong mtInitialize()
        {
            return wrap.mtInitialize();
        }
        public ulong mtUnInitialize()
        {
            return wrap.mtUnInitialize();
        }

        public ulong mtTraceOut(ref mtCLogParam param)
        {
            return wrap.mtTraceOut(ref param);
        }

        public ulong mtCGet(ref mtCRegisterInfo info)
        {
            return wrap.mtCGet(ref info);
        }

        public void mtCRelease(ulong handle)
        {
            wrap.mtCRelease(handle);
        }

        public void mtFreeMemory(IntPtr pVoid)
        {
            wrap.mtFreeMemory(pVoid);
        }

        public IntPtr mtAllocMemory(long nSize)
        {
            return wrap.mtAllocMemory(nSize);
        }

        public int mtInvokeOneWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam data)
        {
            return wrap.mtInvokeOneWay(handle, ref pInvoke, ref data);
        }

        public int mtInvokeTwoWay(ulong handle, ref mtCInvokeParam pInvoke, ref mtCDataParam dataIn, ref mtCDataParam dataOut)
        {
            return wrap.mtInvokeTwoWay(handle, ref pInvoke, ref dataIn, ref dataOut);
        }

        public int mtSetCallback(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify)
        {
            return wrap.mtSetCallback(handle, pfnCallbackOneWay, pfnCallbackTwoWay, pfnStationInfoNotify);
        }

        public int mtTestDelegate(ulong handle, degtOnCallbackOneWay pfnCallbackOneWay, degtOnCallbackTwoWay pfnCallbackTwoWay, degtOnStationInfoNotify pfnStationInfoNotify)
        {
            return wrap.mtSetCallback(handle, pfnCallbackOneWay, pfnCallbackTwoWay, pfnStationInfoNotify);
        }
    }


}
